package  com.wandian.texas;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Event;
import java.awt.Rectangle;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.Date;
import java.util.HashMap;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;

/**
 * 监控服务器
 */
public class ChatServer extends JFrame {
	private static final long serialVersionUID = -2557804639559633012L;

	private JFrame frame;
	private JLabel portLabel;
	private JTextField portField;
	private JButton listenButton;
	private JPanel contentPanel;
	private JScrollPane scrollPane;
	private DefaultListModel listModel;
	private JList infoArea;

	private static final int WIDTH = 400;
	private static final int HEIGHT = 300;

	private ServerSocket ss;
	private HashMap<ChatClient, Integer> sockets;
	private boolean started = false;// 服务器启动标志

	// 构造方法
	public ChatServer() {
	}

	public void init() {
		// 窗口服务器窗口
		frame = new JFrame("服务器");
		frame.setResizable(false);
		// 设置窗口居中
		int screenWidth = (int) java.awt.Toolkit.getDefaultToolkit()
				.getScreenSize().getWidth();
		int screenHeight = (int) java.awt.Toolkit.getDefaultToolkit()
				.getScreenSize().getHeight();
		frame.setBounds((screenWidth - WIDTH) / 2, (screenHeight - HEIGHT) / 2,
				WIDTH, HEIGHT);

		contentPanel = (JPanel) frame.getContentPane();
		contentPanel.setLayout(null);

		portLabel = new JLabel("端口：");
		portField = new JTextField(10);
		listenButton = new JButton("监听");
		listModel = new DefaultListModel();
		infoArea = new JList(listModel);
		scrollPane = new JScrollPane(infoArea);
		listModel.addElement("#服务器消息");
		new Scroller().start();
		infoArea.setBackground(Color.YELLOW);
		portLabel.setBounds(new Rectangle(40, 10, 50, 20));
		portField.setBounds(new Rectangle(100, 10, 100, 20));

		JPanel panel = new JPanel(new BorderLayout());
		JPanel panel1 = new JPanel(new BorderLayout());
		panel.add(listenButton, BorderLayout.CENTER);
		panel.setBounds(new Rectangle(220, 10, 60, 20));
		panel1.setBounds(new Rectangle(290, 10, 60, 20));

		scrollPane.setBounds(18, 50, 355, 200);
		contentPanel.add(portLabel, null);
		contentPanel.add(portField, null);
		contentPanel.add(panel, null);
		contentPanel.add(scrollPane, null);
		// 设置窗口可见
		frame.setVisible(true);

		// 注册监听按钮的鼠标事件
		listenButton.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				String portStr = portField.getText();
				try {
					int port = Integer.valueOf(portStr);
					if (port < 9000 || port > 65535) {
						JOptionPane.showMessageDialog(null,
						"端口为不小于9000且不大于65535的整数，请正确的输入！");
						return;
					} else {
						createServer(port);
						new Receiver().start();
					}
				} catch (NumberFormatException e1) {
					JOptionPane.showMessageDialog(null,
					"端口为不小于9000且不大于65535的整数，请正确的输入！");
					return;
				}
			}
		});

		//
		portField.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				if (e.getKeyCode() == Event.ENTER) {
					String portStr = portField.getText();
					int port = Integer.valueOf(portStr);
					if (port < 9000 || port > 65535) {
						JOptionPane.showMessageDialog(null,
								"端口为不小于9000且不大于65535的整数，请正确的输入！");
						return;
					} else {
						createServer(port);
						new Receiver().start();
					}
				}
			}
		});

		// 注册窗口关闭事件
		frame.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				if (ss != null && !ss.isClosed()) {
					stopServer();
					System.out.println("#服务器已经关闭");
					listModel.addElement("#服务器已经关闭");
				}
				dispose();
				System.exit(0);
			}
		});
	}

	// 创建监听
	public void createServer(int port) {
		try {
			ss = new ServerSocket(port);
			sockets = new HashMap<ChatClient, Integer>();
			started = true;
			System.out.println("#服务器启动成功");
			listModel.addElement("#服务器启动成功");
			portField.setText("");
		}catch (IllegalArgumentException e) {
			listModel.addElement("#服务器启动失败,端口允许范围9000~65535");
			System.out.println("#服务器启动失败");
		} catch (IOException e) {
			System.out.println("#服务器启动失败");
			e.printStackTrace();
		}
	}

	// 关闭服务
	public void stopServer() {
		try {
			if (ss != null) {
				started = false;
				ss.close();
				ss = null;
				dispose();
			}
		} catch (IOException e) {
			System.out.println("#服务器关闭失败");
			e.printStackTrace();
		}
	}

	// 开启一个线程用来接收客户端的连接
	class Receiver extends Thread {

		@Override
		public void run() {
			while (started) {
				try {
					Socket s = ss.accept();
					ChatClient client = new ChatClient();
					client.setSocket(s);
					client.setStart(false);
					sockets.put(client, 0);
					String remoteSocketAddress = client.getSocket()
							.getRemoteSocketAddress().toString();
					int start = remoteSocketAddress.indexOf("/") + 1;
					int end = remoteSocketAddress.indexOf(":");
					listModel.addElement("#CLIENT端为"
							+ remoteSocketAddress.substring(start, end)
							+ "连接成功……");
					DataOutputStream dos = new DataOutputStream(client
							.getSocket().getOutputStream());
					dos.writeUTF("#连接成功");
					new CommandReceiver(client).start();
				} catch (SocketException e) {

				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		}
	}

	// 负责接受客户端命令的线程类
	class CommandReceiver extends Thread {
		private ChatClient client;
		private DataInputStream bis;
		private DataOutputStream dos;
		private Thread thread;
		private boolean flag = true;

		public CommandReceiver(ChatClient client) {
			this.client = client;
			try {
				bis = new DataInputStream(client.getSocket().getInputStream());
				dos = new DataOutputStream(client.getSocket().getOutputStream());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		@Override
		public void run() {
			while (flag) {
				try {
					String command = bis.readUTF();
					if (command.equals("start")) {
						client.setStart(true);
						ChatThread ct = new ChatThread(client);
						thread = new Thread(ct);
						thread.start();
					} else if (command.equals("stop")) {
						if (thread != null) {
							client.setStart(false);
							String remoteSocketAddress = client.getSocket()
									.getRemoteSocketAddress().toString();
							int start = remoteSocketAddress.indexOf("/") + 1;
							int end = remoteSocketAddress.indexOf(":");
							listModel.addElement("#CLIENT端为"
									+ remoteSocketAddress.substring(start, end)
									+ "停止发送时间……");
							dos.writeUTF("#已发送时间次数为" + sockets.get(client)
									+ "次:BYE-BYE!!!!");
							// 重置发送时间次数
							sockets.put(client, 0);
						} else {
							dos.writeUTF("#start命令尚未执行……");
						}
					} else {
						dos.writeUTF("#命令未完定义，命令为" + command);
					}
				} catch (SocketException e) {
					String remoteSocketAddress = client.getSocket()
							.getRemoteSocketAddress().toString();
					int start = remoteSocketAddress.indexOf("/") + 1;
					int end = remoteSocketAddress.indexOf(":");
					System.out.println("#客户端"
							+ remoteSocketAddress.substring(start, end) + "关闭");
					flag = false;
					client.setStart(false);
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	// 负责发送时间的线程类
	class ChatThread implements Runnable {

		private ChatClient client;
		private DataOutputStream dos;

		public ChatThread(ChatClient client) {
			this.client = client;
			try {
				dos = new DataOutputStream(client.getSocket().getOutputStream());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		@SuppressWarnings("deprecation")
		public void run() {
			while (client.isStart()) {
				try {
					String remoteSocketAddress = client.getSocket()
							.getRemoteSocketAddress().toString();
					int start = remoteSocketAddress.indexOf("/") + 1;
					int end = remoteSocketAddress.indexOf(":");
					listModel.addElement("#CLIENT端为"
							+ remoteSocketAddress.substring(start, end)
							+ ",开始同步时间……");
					String msg = "#当前时间：" + new Date().toLocaleString();
					dos.writeUTF(msg);
					int count = sockets.get(client).intValue() + 1;
					sockets.put(client, count);
					Thread.sleep(8000);
				} catch (IOException e1) {
					e1.printStackTrace();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

	// 负责滚动的线程
	class Scroller extends Thread {
		@Override
		public void run() {
			while (true) {
				scrollToView();
			}
		}
	}

	// Jlist的滚动方法
	private void scrollToView() {
		int lastIndex = listModel.getSize();
		Rectangle rect = infoArea.getCellBounds(lastIndex - 1, lastIndex - 1);
		scrollPane.getViewport().scrollRectToVisible(rect);
	}

	public static void main(String[] args) {
		new ChatServer().init();
	}

}
